package EP.MetricasContenido;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
* @class TfxIDF
* @author Mauricio Alvarez.
* @brief Esta clase representa la clase TfxIDF, correspondiente a una entidad principal (EP).
*/
public class TfxIDF {

    /**
     *  @var int id_pagina
     *  @brief identificador de la página en la BD.
    */
    private int id_pagina;
    /**
     *  @var String Termino
     *  @brief Termino correspondiente a la consulta Q={q1,q2,...,qn}.
    */
    private String Termino;
    /**
     *  @var float TFij_SN
     *  @brief Frecuencia del termino i en la pagina j. (SIN NORMALIZAR)
    */
    private double TFij_SN = 0;
    /**
     *  @var float TFij_N
     *  @brief Frecuencia del termino i en la pagina j (NORMALIZADO).
    */
    private double TFij_N = 0;
    /**
     *  @var float TFij_S
     *  @brief Frecuencia del termino i en la pagina j (SUAVISADO).
    */
    private double TFij_S = 0;
    /**
     *  @var private double IDF
     *  @brief Valor del IDF para el lote de páginas obtenidas de la BD.
    */
    private double IDF = 0;
    /**
     *  @var private double IDF_O
     *  @brief Valor del IDF (Okapi BM25) para el lote de páginas obtenidas de la BD.
    */
    private double IDF_O = 0;
    /**
     *  @var private double TfxIDF_SN
     *  @brief Valor del TfxIDF_SN para el lote de páginas obtenidas de la BD. (SIN NORMALIZAR)
    */
    private double TfxIDF_SN = 0;
     /**
     *  @var private double TfxIDF_N
     *  @brief Valor del TfxIDF_N para el lote de páginas obtenidas de la BD. (NORMALIZADO)
    */
    private double TfxIDF_N = 0;
    /**
     *  @var private double TfxIDF_S
     *  @brief Valor del TfxIDF_S para el lote de páginas obtenidas de la BD. (SUAVISADO)
    */
    private double TfxIDF_S = 0;
    /**
     *  @var private double TfxIDF_O_SN
     *  @brief Valor del TfxIDF_O_SN para el lote de páginas obtenidas de la BD. (PROBABILISTICO)
    */
    private double TfxIDF_O_SN = 0;
    /**
     *  @var private double TfxIDF_O_N
     *  @brief Valor del TfxIDF_O_N para el lote de páginas obtenidas de la BD. (PROBABILISTICO)
    */
    private double TfxIDF_O_N = 0;
    /**
     *  @var private double TfxIDF_O_S
     *  @brief Valor del TfxIDF_O_S para el lote de páginas obtenidas de la BD. (PROBABILISTICO)
    */
    private double TfxIDF_O_S = 0;
    /**
     *  @var private TF tf
     *  @brief Variable global del tipo clase TF.
    */
    private TF tf;
    /**
     *  @var private IDF idf
     *  @brief Variable global del tipo clase IDF.
    */
    private IDF idf;


    //////////////////////
    // CONSTRUCTOR
    //////////////////////
    public TfxIDF()
    {
        tf = new TF();
        idf = new IDF();
    }


    //////////////////////
    // GETTER Y SETTER
    //////////////////////
    public double getIDF() {
        return IDF;
    }

    public void setIDF(double IDF) {
        this.IDF = IDF;
    }

    public double getIDF_O() {
        return IDF_O;
    }

    public void setIDF_O(double IDF_O) {
        this.IDF_O = IDF_O;
    }

    public double getTFij_N() {
        return TFij_N;
    }

    public void setTFij_N(double TFij_N) {
        this.TFij_N = TFij_N;
    }

    public double getTFij_S() {
        return TFij_S;
    }

    public void setTFij_S(double TFij_S) {
        this.TFij_S = TFij_S;
    }

    public double getTFij_SN() {
        return TFij_SN;
    }

    public void setTFij_SN(double TFij_SN) {
        this.TFij_SN = TFij_SN;
    }

    public String getTermino() {
        return Termino;
    }

    public void setTermino(String Termino) {
        this.Termino = Termino;
    }

    public double getTfxIDF_N() {
        return TfxIDF_N;
    }

    public void setTfxIDF_N(double TfxIDF_N) {
        this.TfxIDF_N = TfxIDF_N;
    }

    public double getTfxIDF_O_N() {
        return TfxIDF_O_N;
    }

    public void setTfxIDF_O_N(double TfxIDF_O_N) {
        this.TfxIDF_O_N = TfxIDF_O_N;
    }

    public double getTfxIDF_O_S() {
        return TfxIDF_O_S;
    }

    public void setTfxIDF_O_S(double TfxIDF_O_S) {
        this.TfxIDF_O_S = TfxIDF_O_S;
    }

    public double getTfxIDF_O_SN() {
        return TfxIDF_O_SN;
    }

    public void setTfxIDF_O_SN(double TfxIDF_O_SN) {
        this.TfxIDF_O_SN = TfxIDF_O_SN;
    }

    public double getTfxIDF_S() {
        return TfxIDF_S;
    }

    public void setTfxIDF_S(double TfxIDF_S) {
        this.TfxIDF_S = TfxIDF_S;
    }

    public double getTfxIDF_SN() {
        return TfxIDF_SN;
    }

    public void setTfxIDF_SN(double TfxIDF_SN) {
        this.TfxIDF_SN = TfxIDF_SN;
    }

    public int getId_pagina() {
        return id_pagina;
    }

    public void setId_pagina(int id_pagina) {
        this.id_pagina = id_pagina;
    }


    //////////////////////
    // OPERACIONES
    //////////////////////

    /**
     * @brief Calcula el puntaje TfxIDF.
     * @param Lista de resultados TF e IDF y la opcion sobre el contenido del
     * cálculo (1:BODY/2:SURROUND TEXT).
     * @return Map<Integer, List>
    */
    public Map<Integer, List> CalcularTfxIDF(Map<Integer, List> ResultadosTF,
                                      Map<String, List> ResultadosIDF,
                                      int OpcionContenido)
    {

        ////////////////////////////////////////////////////////////////////////
        //PASO 0: Segun la selección de OpcionContenido (1:BODY/2:SURROUND TEXT)
        //        se calcula el TfxIDF:
        ////////////////////////////////////////////////////////////////////////

        //Atributos metricas:
        int id_pagina;
        int id_relacion_pag;
        int pag_id_pagina;
        String termino;
        double TF_SN;
        double TF_N;
        double TF_S;
        double IDF;
        double IDF_O;
        double TfxIDF_SN;
        double TfxIDF_N;
        double TfxIDF_S;
        double TfxIDF_O_SN;
        double TfxIDF_O_N;
        double TfxIDF_O_S;

        ////////////
        // BODY   //
        ////////////
        if (OpcionContenido == 1)
        {

            System.out.println("***************************************");
            System.out.println("**    CALCULO DE TFxIDF (BODY)       **");
            System.out.println("***************************************");

            Map<Integer, List> ResultadoTfxIDF = new HashMap();
            TfxIDF tfxidf;


            ///////////////////////////////////////////
            //PASO 1: Para cada página en TF hacer:
            ///////////////////////////////////////////
            Set set = ResultadosTF.entrySet();
            Iterator it = set.iterator();

            while (it.hasNext())
            {
                Map.Entry par = (Map.Entry)it.next();
                //Se obtiene el id_pagina:
                id_pagina = (Integer) par.getKey();
                //Se obtiene para la página los resultados TF del termino i:
                List<TF> paginasTF = new ArrayList();
                paginasTF = (List<TF>) par.getValue();

                List<TfxIDF> ResultadoPaginaTfxIDF = new ArrayList<TfxIDF>();


                //Para cada página hacer:
                for (int i=0; i<paginasTF.size(); i++)
                {
                    id_pagina = paginasTF.get(i).getId_pagina();
                    //Se obtiene el termino que obtuvo los TFs:
                    termino = paginasTF.get(i).getTermino();
                    //Se obtiene el TF_SN:
                    TF_SN = paginasTF.get(i).getTFij_SN();
                    //Se obtiene el TF_N:
                    TF_N = paginasTF.get(i).getTFij_N();
                    //Se obtiene el TF_S:
                    TF_S = paginasTF.get(i).getTFij_S();

                    //Se obtiene el IDF correspondiente al termino en el HashMap ResultadosIDF:
                    List<IDF> paginasIDF = new ArrayList();
                    paginasIDF = ResultadosIDF.get(termino);

                    //Para cada resultado IDF para cada página hacer:
                    for (int j=0; j<paginasIDF.size(); j++)
                    {

                        //Si el termino es igual al termino del resultado IDF:
                        if ((termino.compareToIgnoreCase(paginasIDF.get(j).getTermino()) == 0 ))
                        {

                            //Se obtiene el IDF e IDF_O:
                            IDF = paginasIDF.get(j).getIDF();
                            IDF_O = paginasIDF.get(j).getIDF_O();

                            //Se calculan los TfxIDF:
                            //(1) Se calcula el TfxIDF_SN:
                            TfxIDF_SN = TF_SN * IDF;

                            //(2) Se calcula el TfxIDF_N:
                            TfxIDF_N = TF_N * IDF;

                            //(3) Se calcula el TfxIDF_S:
                            TfxIDF_S = TF_S * IDF;

                            //(4) Se calcula el TfxIDF_O_SN:
                            TfxIDF_O_SN = TF_SN * IDF_O;

                            //(5) Se calcula el TfxIDF_O_N:
                            TfxIDF_O_N = TF_N * IDF_O;

                            //(6) Se calcula el TfxIDF_O_S:
                            TfxIDF_O_S = TF_S * IDF_O;

                            //Se guarda el estudio para la página seleccionada:
                            tfxidf = new TfxIDF();
                            tfxidf.setId_pagina(id_pagina);
                            tfxidf.setTermino(termino);
                            tfxidf.setTFij_SN(TF_SN);
                            tfxidf.setTFij_N(TF_N);
                            tfxidf.setTFij_S(TF_S);
                            tfxidf.setIDF(IDF);
                            tfxidf.setIDF_O(IDF_O);
                            tfxidf.setTfxIDF_SN(TfxIDF_SN);
                            tfxidf.setTfxIDF_N(TfxIDF_N);
                            tfxidf.setTfxIDF_S(TfxIDF_S);
                            tfxidf.setTfxIDF_O_SN(TfxIDF_O_SN);
                            tfxidf.setTfxIDF_O_N(TfxIDF_O_N);
                            tfxidf.setTfxIDF_O_S(TfxIDF_O_S);

                            ResultadoPaginaTfxIDF.add(tfxidf);


                            //BORRAR ESTOOOOO!!!:!::!:!:!:!:!:!:!:!:!:!:!!:::!:!::!:!:!

                            System.out.println("------------------------------------");
                            System.out.println("id_pagina: "+ id_pagina);
                            System.out.println("termino: "+ termino);
                            System.out.println("TF_SN: "+ TF_SN);
                            System.out.println("TF_N: "+ TF_N);
                            System.out.println("TF_S: "+ TF_S);
                            System.out.println("IDF: "+ IDF);
                            System.out.println("IDF_O: "+ IDF_O);
                            System.out.println("TfxIDF_SN: "+ TfxIDF_SN);
                            System.out.println("TfxIDF_N: "+ TfxIDF_N);
                            System.out.println("TfxIDF_S: "+ TfxIDF_S);
                            System.out.println("TfxIDF_O_SN: "+ TfxIDF_O_SN);
                            System.out.println("TfxIDF_O_N: "+ TfxIDF_O_N);
                            System.out.println("TfxIDF_O_S: "+ TfxIDF_O_S);
                            System.out.println("++++++++++++++++++++++++++++++++++++");

                            //BORRAR ESTOOOOO!!!:!::!:!:!:!:!:!:!:!:!:!:!!:::!:!::!:!:!


                        }//FIN if comparación id_pagina

                    }//FIN while paginasIDF

                }//FIN for páginas


                //PASO: Se guarda en el Map los resultados TF-IDF para una página y
                //      todos los terminos asociados a la consulta.
                ResultadoTfxIDF.put(id_pagina, (ArrayList) ResultadoPaginaTfxIDF);


            }//FIN while ResultadosTF

            return ResultadoTfxIDF;

        }//FIN IF BODY


        ////////////////////
        // SURROUND TEXT  //
        ////////////////////

        if (OpcionContenido == 2)
        {
            System.out.println("************************************************");
            System.out.println("**    CALCULO DE TFxIDF (SURROUND TEXT)       **");
            System.out.println("************************************************");

            Map<Integer, List> ResultadoTfxIDFST = new HashMap();
            TfxIDF tfxidf;


            ///////////////////////////////////////////
            //PASO 1: Para cada ST en TF hacer:
            ///////////////////////////////////////////
            Set set = ResultadosTF.entrySet();
            Iterator it = set.iterator();

            while (it.hasNext())
            {
                Map.Entry par = (Map.Entry)it.next();
                //Se obtiene el id_relacion_pag:
                id_relacion_pag = (Integer) par.getKey();
                //Se obtiene para casa ST de la página los resultados TF del termino i:
                List<TF> surroundTextTF = new ArrayList();
                surroundTextTF = (List<TF>) par.getValue();

                List<TfxIDF> ResultadoST_TfxIDFST = new ArrayList();


                //Para cada ST de cada página y cada termino, hacer:
                for (int i=0; i<surroundTextTF.size(); i++)
                {
                    //Se obtiene el id_relacion_pag:
                    id_relacion_pag = surroundTextTF.get(i).getId_relacion_pag();
                    //Se obtiene el id_pagina (DESTINO):
                    id_pagina = surroundTextTF.get(i).getId_pagina();
                    //Se obtiene el pag_id_pagina (ORIGEN):
                    pag_id_pagina = surroundTextTF.get(i).getPag_id_pagina();
                    //Se obtiene el termino que obtuvo los TFs:
                    termino = surroundTextTF.get(i).getTermino();
                    //Se obtiene el TF_SN:
                    TF_SN = surroundTextTF.get(i).getTFij_SN();
                    //Se obtiene el TF_N:
                    TF_N = surroundTextTF.get(i).getTFij_N();
                    //Se obtiene el TF_S:
                    TF_S = surroundTextTF.get(i).getTFij_S();

                    //Se obtiene el IDF correspondiente al termino en el HashMap ResultadosIDF:
                    List<IDF> surroundTextIDF = new ArrayList();
                    surroundTextIDF = ResultadosIDF.get(termino);

                    //Para cada resultado IDF para cada página hacer:
                    for (int j=0; j<surroundTextIDF.size(); j++)
                    {

                        //Si el termino es igual al termino del resultado IDF:
                        if ((termino.compareToIgnoreCase(surroundTextIDF.get(j).getTermino()) == 0 ))
                        {

                            //Se obtiene el IDF e IDF_O:
                            IDF = surroundTextIDF.get(j).getIDF();
                            IDF_O = surroundTextIDF.get(j).getIDF_O();

                            //Se calculan los TfxIDF:
                            //(1) Se calcula el TfxIDF_SN:
                            TfxIDF_SN = TF_SN * IDF;

                            //(2) Se calcula el TfxIDF_N:
                            TfxIDF_N = TF_N * IDF;

                            //(3) Se calcula el TfxIDF_S:
                            TfxIDF_S = TF_S * IDF;

                            //(4) Se calcula el TfxIDF_O_SN:
                            TfxIDF_O_SN = TF_SN * IDF_O;

                            //(5) Se calcula el TfxIDF_O_N:
                            TfxIDF_O_N = TF_N * IDF_O;

                            //(6) Se calcula el TfxIDF_O_S:
                            TfxIDF_O_S = TF_S * IDF_O;

                            //Se guarda el estudio para la página seleccionada:
                            tfxidf = new TfxIDF();
                            tfxidf.setId_pagina(id_pagina);
                            tfxidf.setTermino(termino);
                            tfxidf.setTFij_SN(TF_SN);
                            tfxidf.setTFij_N(TF_N);
                            tfxidf.setTFij_S(TF_S);
                            tfxidf.setIDF(IDF);
                            tfxidf.setIDF_O(IDF_O);
                            tfxidf.setTfxIDF_SN(TfxIDF_SN);
                            tfxidf.setTfxIDF_N(TfxIDF_N);
                            tfxidf.setTfxIDF_S(TfxIDF_S);
                            tfxidf.setTfxIDF_O_SN(TfxIDF_O_SN);
                            tfxidf.setTfxIDF_O_N(TfxIDF_O_N);
                            tfxidf.setTfxIDF_O_S(TfxIDF_O_S);

                            ResultadoST_TfxIDFST.add(tfxidf);


                            //BORRAR ESTOOOOO!!!:!::!:!:!:!:!:!:!:!:!:!:!!:::!:!::!:!:!

                            System.out.println("------------------------------------");
                            System.out.println("id_pagina: "+ id_pagina);
                            System.out.println("termino: "+ termino);
                            System.out.println("TF_SN: "+ TF_SN);
                            System.out.println("TF_N: "+ TF_N);
                            System.out.println("TF_S: "+ TF_S);
                            System.out.println("IDF: "+ IDF);
                            System.out.println("IDF_O: "+ IDF_O);
                            System.out.println("TfxIDF_SN: "+ TfxIDF_SN);
                            System.out.println("TfxIDF_N: "+ TfxIDF_N);
                            System.out.println("TfxIDF_S: "+ TfxIDF_S);
                            System.out.println("TfxIDF_O_SN: "+ TfxIDF_O_SN);
                            System.out.println("TfxIDF_O_N: "+ TfxIDF_O_N);
                            System.out.println("TfxIDF_O_S: "+ TfxIDF_O_S);
                            System.out.println("++++++++++++++++++++++++++++++++++++");

                            //BORRAR ESTOOOOO!!!:!::!:!:!:!:!:!:!:!:!:!:!!:::!:!::!:!:!


                        }//FIN if comparación id_pagina

                    }//FIN while paginasIDF

                }//FIN for páginas


                //PASO: Se guarda en el Map los resultados TF-IDF para una página y
                //      todos los terminos asociados a la consulta.
                ResultadoTfxIDFST.put(id_relacion_pag, ResultadoST_TfxIDFST);


            }//FIN while ResultadosTF

            return ResultadoTfxIDFST;

        }//FIN IF SURROUND TEXT

        return null;

    }//FIN CalcularTfxIDF

}//FIN CLASE TfxIDF